<script setup>
import { ref } from 'vue';
import { PictureOutlined, FileExcelOutlined } from '@ant-design/icons-vue';
import { REQU, toFormData } from '@/net/requ.js';
import { useTaskAssign } from './api/use-task-assign.js';
import { useQuesAssign } from './api/use-ques-assign.jsx';
import { useFile } from './api/use-file.js';
import { useModel } from './api/use-model.js';
import { message } from 'ant-design-vue';

const IsImg = R.compose( R.includes('image'), R.prop('type') );
const props = defineProps(['id']);
const taskId = props.id;

const fileUrls = ref([]);
const fileTotal = ref(0);
const { loading, taskInfo, singlePackageNum, dataSource, main, submit } = useTaskAssign({ id: props.id, fileTotal });
const { uploadable, controller, fileList, countUploaded, uploading, uploadFailedList, handleChange } = useFile(props.id);
const { handleChangeXls, columns, isAssignedForAll } = useQuesAssign({ dataSource, fileList, fileTotal, countUploaded, uploadFailedList });
const { modelList, modelUrl, handleChangeModelList, customRequestModel } = useModel(props.id);

function customRequest({ file, onSuccess, onError }) {
  if (controller.value.signal.aborted) {
    ++countUploaded.value;
    return;
  }

  fileUrls.value.push(`/group1/${ taskId }/${ file.name }`);

  REQU(
    '/upload',
    {
      signal: controller.value.signal,
      method: 'POST',
      body: toFormData({
        file,
        scene: 'default',
        filename: '',
        output: 'json2',
        path: taskId,
        code: '',
        auth_token: '',
        submit: 'upload',
      })
    },
    { showError: false }
  )
  .then(result => {
    ++fileTotal.value;
    return onSuccess(result, file);
  })
  .catch(error => onError(error))
  .finally(() => ++countUploaded.value);
}

function retry() {
  uploadFailedList.value.forEach(file => {
    file.status = 'uploading';
    customRequest({
      file,
      onSuccess: (result, file) => file.status = 'done',
      onError: error => file.status = 'error',
    })
  });
}

const quesAssignColumns = ref(
  columns.value.concat({
    title: '题包数',
    width: '6em',
    customRender: ({ record }) => R.compose( Math.ceil, R.divide(R.__, singlePackageNum.value), R.prop('fileNum') )(record),
  }),
);

main();
</script>

<template>
  <div class="task-assign">
    <a-spin :spinning="loading">
      <template v-if="taskInfo">
        <header>
          <h3>任务名称：{{ taskInfo?.taskName || '--' }}</h3>
          <a-button
            v-exist:task="'完成'"
            :disabled="!(0 < fileTotal)"
            type="primary"
            @click="() => submit({
              fileUrls,
              modelUrl: JSON.stringify(modelUrl),
            })">
            完成
          </a-button>
        </header>
      
        <div class="mod-bar">
          预标注模型：
          <a-upload
            v-model:fileList="modelList"
            accept=".onnx"
            :custom-request="customRequestModel"
            @change="handleChangeModelList"
          >
            <template v-if="0 == modelList.length">
              <a-button>上传</a-button>
            </template>  
          </a-upload>
        </div>
      
        <a-upload-dragger
          v-model:fileList="fileList"
          multiple
          :disabled="!uploadable"
          :show-upload-list="false"
          accept=".jpg,.jpeg,.png,.gif"
          :custom-request="customRequest"
          @change="handleChange"
        >
          <picture-outlined style="font-size: 2em; color: rgba(0,0,0,.45)" />
          <p class="ant-upload-text">将图片拖到此处或点击选择，按住 Ctrl 可同时多选，单次最多可选100张</p>
          <p class="ant-upload-hint">仅支持上传 jpg / jpeg / png / gif 格式文件</p>
        </a-upload-dragger>
      
        <div class="sub-bar">
          <a-form-item label="已上传">{{ fileTotal }}</a-form-item>
          <!-- <template v-if="false">
            <a-form-item label="已失败">
              {{ uploadFailedList.length }}
              <a-button>
                <template #icon><redo-outlined></redo-outlined></template>
              </a-button>
            </a-form-item>
          </template> -->
          <a-form-item label="单包题数">
            <a-input-number v-model:value="singlePackageNum" :min="20" :step="1"></a-input-number>
          </a-form-item>
          <template v-if="uploading">上传中...</template>
      
          <a-button
            type="danger"
            @click="() => {
              controller.abort();
              message.info('已取消上传');
            }"
            style="margin-left: auto;">
            取消上传
          </a-button>
        </div>
      
        <div class="table-container">
          <template v-if="0 < fileTotal && !isAssignedForAll">
            <p class="for-all-tip">请为所有人分配题数</p>
          </template>
      
          <label>
            <input hidden type="file" accept=".xls,.xlsx" @change="handleChangeXls">
            <a-button
              type="link"
              :disabled="loading"
              @click="event => event.currentTarget.parentElement.click()">
              <template #icon><file-excel-outlined /></template>
              导入
            </a-button>
          </label>
          
          <a-table
            :pagination="false"
            row-key="userId"
            :data-source="dataSource"
            :columns="quesAssignColumns">        
          </a-table>
        </div>
      </template>
    </a-spin>
  </div>
</template>

<style>
.task-assign .mod-bar {
  display: flex;
  align-items: center;
  height: 32px;
  margin-bottom: 1em;
}

.task-assign .mod-bar .ant-upload-list-item { margin-top: 0; }
</style>

